/**
 * 
 */
package be.donovan.gui.helper.components;

import java.awt.event.ActionEvent;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Vector;

import javax.swing.JButton;

import org.springframework.util.ReflectionUtils;

import be.donovan.gui.helper.ServiceLocator;
import be.donovan.model.persist.PersistenceHelper;


public abstract class AbstractDTOController<T> extends AbstractController<DTOInterfacePanel> {

	public abstract Class<T> getDtoClass();

	protected List<T> toSaveOrUpdate = new ArrayList<T>();

	private boolean validationSucceeded = false;

//	private ValidationException setterException = null;

	private AbstractDTOController additionalController = null;

	public void onCloseAction(ActionEvent e) {
		stop();
	}

	@SuppressWarnings("unchecked")
	public void onNewAction(ActionEvent e) {
		T dto;
		try {
			dto = (T) getDtoClass().newInstance();
			((MVCTableModel) getView().catalogTable.getModel()).add(dto);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

//	@SuppressWarnings("unchecked")
//	public void preSaveAllAction(ActionEvent e) {
//		toSaveOrUpdate.clear();
//		getView().catalogTable.editingStopped(null);
//		getView().buttonSave.requestFocus();
//		for (int rowIndex = 0; rowIndex < getView().catalogTable.getRowCount(); rowIndex++) {
//			final AbstractDTO t = ((EditableMVCTableModel) getView().catalogTable.getModel())
//					.fromRowVector(getView().catalogTable.convertRowIndexToModel(rowIndex));
//			if ((t instanceof AbstractDTO) && (!((AbstractDTO)t).isDirty())) {
//				// do nothing
//			} else
//				toSaveOrUpdate.add((T) t);
//		}
//		validateAll();
//	}

//	private void validateAll() {
//		ValidationException ve = new ValidationException();
//		if (setterException != null)
//			ve.addFaults(setterException.getFaults());
//		if (ve.containsFaults())
//			JOptionPane.showMessageDialog(getView(), ve.toString());
//		else
//			validationSucceeded = true;
//	}

	public void onSaveAllAction(ActionEvent e) throws Exception {
			saveAll();
	}



	@Override
	public void initListeners() {
		setupActionListener(getView().buttonClose, "Close");

		setupActionListener(getView().buttonSave, "SaveAll");

		setupActionListener(getView().buttonNew, "New");
	}

	public void maintainCatalog() {
		getView().setName("Maintain " + getDtoClass().getSimpleName());
		getView().getController().start();
	}

	@SuppressWarnings("unchecked")
	@Override
	public void initData() {
		MVCTableModel tableModel = new EditableMVCTableModel(readAll(), getPropertyGetters(), getPropertySetters(),
				getHeading(), this);
		getView().catalogTable.setModel(tableModel);
		JXTableDecorator.setStyleAndEditors(getView().catalogTable, "catalogTable",
				getView().scrollPane, "Manage Catalog");

		setTableCellEditors();
	}

	public void setTableCellEditors() {
	}

	/**
	 * Add a button to the buttonsPanel contained into the
	 * <code>AbstractDTOPanel</code>, and setup <code>ActionListener</code>
	 * to invoke on button click.<br>
	 * <b>Don't forget to override
	 * <code>onAdditionalButtonAction(ActionEvent e)</code> to do something
	 * with the button.</b>
	 * 
	 * @param text :
	 *            text to display on the button
	 * @param controller :
	 *            controller witch override the onAdditionalButtonAction method
	 *            called on this button click
	 */
	public void addAdditionalButton(String text, AbstractDTOController controller) {
		JButton additionalButton = new JButton();
		getView().buttonsPanel.add(additionalButton);
		additionalButton.setText(text);
		additionalController = controller;
		setupActionListener(additionalButton, "AdditionalButton");
	}
	public Vector<String> getHeading() {
		Vector<String> heading = new Vector<String>();
		Method[] methods = ReflectionUtils.getAllDeclaredMethods(getDtoClass());
		for (Method method : methods) {
			if(method.getName().startsWith("get")){
				heading.add(method.getName().substring(3));
			}
		}
		heading.remove(heading.size()-1);
		System.out.println("AllPersonController.getHeading()"+heading);
		return heading;
	}

	public Vector<String> getPropertyGetters() {
		Vector<String> heading = new Vector<String>();
		Method[] methods = ReflectionUtils.getAllDeclaredMethods(getDtoClass());
		for (Method method : methods) {
			if(method.getName().startsWith("get")){
				heading.add(method.getName());
			}
		}
		heading.remove(heading.size()-1);
		System.out.println("AllPersonController.getPropertyGetters()"+heading);
		return heading;
		
	}

	public Vector<String> getPropertySetters() {
		Vector<String> heading = new Vector<String>();
		Method[] methods = ReflectionUtils.getAllDeclaredMethods(getDtoClass());
		for (Method method : methods) {
			if(method.getName().startsWith("get")){
				heading.add("set"+(method.getName().substring(3)));
			}
		}
		heading.remove(heading.size()-1);
		System.out.println("AllPersonController.getPropertySetters()"+heading);
		return heading;	}

	public Collection<T> readAll() {
		return ServiceLocator.getService(PersistenceHelper.class).findAll(getDtoClass());
	}
	@SuppressWarnings("unchecked")
	public void saveAll() {
		ServiceLocator.getService(PersistenceHelper.class).saveAll(((MVCTableModel<T>)getView().catalogTable.getModel()).getData());
		
	}

//	/**
//	 * @param e
//	 */
//	@SuppressWarnings("unchecked")
//	public void onAdditionalButtonAction(ActionEvent e) {
//		if (additionalController != null) {
//			AbstractDTOPanel view = new AbstractDTOPanel();
//			view.setController(additionalController);
//			additionalController.maintainCatalog();
//		}
//	}
//
//	public void setSetterException(ValidationException setterException) {
//		this.setterException = setterException;
//	}

}
